﻿// Pipeline Component Library Example
// ----------------------------------
// Colin Bowern (colinbowern@hotmail.com)
// January 2007
//
// Copyright (c) 2007 Colin Bowern
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// * The above copyright notice and this permission notice shall be included in
//   all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#region References
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Runtime = Microsoft.CommerceServer.Runtime;
using RockstarGuys.PipelineComponents;
using System;
using System.Collections.Generic;
using System.Text;
#endregion

namespace RockstarGuys.PipelineComponents.Tests
{
    /// <summary>
    ///This is a test class for RockstarGuys.PipelineComponents.Dictionary and is intended
    ///to contain all RockstarGuys.PipelineComponents.Dictionary Unit Tests
    ///</summary>
    [TestClass()]
    public class DictionaryTest
    {
        #region Constructor
        /// <summary>
        /// Positive: Default constructor
        /// </summary>
        [TestMethod]
        public void ConstructorTest1()
        {
            Dictionary target = new Dictionary();
            Assert.IsNotNull(target);
        }

        /// <summary>
        /// Positive: Container constructor
        /// </summary>
        [TestMethod]
        public void ConstructorTest2()
        {
            Runtime.IDictionary container = new Runtime.DictionaryClass();
            container["foo"] = "bar";

            Dictionary actual = new Dictionary(container);
            Assert.IsNotNull(actual);
            Assert.AreEqual<int>(1, actual.Count);
            Assert.AreEqual<object>(container["foo"], actual["foo"]);
        }
        #endregion

        #region Add
        /// <summary>
        /// Positive: Proper value
        /// </summary>
        [TestMethod]
        public void AddTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            object value = "bar";

            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);
            Assert.AreEqual<object>(value, target[key]);
        }

        /// <summary>
        /// Positive: Proper value multiple times
        /// </summary>
        [TestMethod]
        public void AddTest2()
        {
            Dictionary target = new Dictionary();

            string key1 = "foo";
            object value1 = "bar";

            target.Add(key1, value1);
            target.Add(key1, value1);

            string key2 = "fooey";
            string value2 = "barred";

            target.Add(key2, value2);
            Assert.AreEqual<int>(2, target.Count);
            Assert.AreEqual<object>(value1, target[key1]);
            Assert.AreEqual<object>(value2, target[key2]);
        }

        /// <summary>
        /// Positive: Proper value as object
        /// </summary>
        [TestMethod]
        public void AddTest3()
        {
            Dictionary target = new Dictionary();

            object key = "foo";
            object value = "bar";

            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);
            Assert.AreEqual<object>(value, target[key]);
        }

        /// <summary>
        /// Negative: Null value.
        /// </summary>
        [TestMethod]
        public void AddNegativeTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            object value = null;

            target.Add(key, value);
            Assert.AreEqual<int>(0, target.Count);
        }

        /// <summary>
        /// Fault: Null key.
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentNullException))]
        public void AddFaultTest1()
        {
            Dictionary target = new Dictionary();

            string key = null;
            object value = "bar";

            target.Add(key, value);
            Assert.Fail("Exception not thrown.");
        }

        /// <summary>
        /// Fault: Non-string key
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentTypeException))]
        public void AddFaultTest2()
        {
            Dictionary target = new Dictionary();

            object key = int.MaxValue;
            object value = "bar";

            target.Add(key, value);
            Assert.Fail("Exception not thrown.");
        }
        #endregion

        #region Clear
        /// <summary>
        /// Positive: Values in list
        /// </summary>
        [TestMethod]
        public void ClearTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            target.Clear();
            Assert.AreEqual<int>(0, target.Count);
        }

        /// <summary>
        /// Positive: Empty list
        /// </summary>
        [TestMethod]
        public void ClearTest2()
        {
            Dictionary target = new Dictionary();

            Assert.AreEqual<int>(0, target.Count);

            target.Clear();
            Assert.AreEqual<int>(0, target.Count);
        }
        #endregion

        #region Contains/ContainsKey
        /// <summary>
        /// Positive: Proper key/value
        /// </summary>
        [TestMethod]
        public void ContainsTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            bool actual = target.Contains(key);
            Assert.IsTrue(actual);
        }

        /// <summary>
        /// Positive: Proper key/value
        /// </summary>
        [TestMethod]
        public void ContainsTest2()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            bool actual = target.Contains(key.ToUpper());
            Assert.IsTrue(actual);
        }

        /// <summary>
        /// Negative: No match
        /// </summary>
        [TestMethod]
        public void ContainsNegativeTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            key = "fooey";
            bool actual = target.Contains(key);
            Assert.IsFalse(actual);
        }

        /// <summary>
        /// Fault: Null key
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentNullException))]
        public void ContainsFaultTest1()
        {
            Dictionary target = new Dictionary();

            bool actual = target.Contains(null);
            Assert.Fail("Exception not thrown.");
        }
        #endregion

        #region Contains/ContainsValue
        /// <summary>
        /// Positive: Proper key/value
        /// </summary>
        [TestMethod]
        public void ContainsValueTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            bool actual = target.ContainsValue(value);
            Assert.IsTrue(actual);
        }

        /// <summary>
        /// Positive: No match
        /// </summary>
        [TestMethod]
        public void ContainsValueNegativeTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            bool actual = target.ContainsValue(value.ToUpper());
            Assert.IsFalse(actual);
        }

        /// <summary>
        /// Negative: No match
        /// </summary>
        [TestMethod]
        public void ContainsValueNegativeTest2()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            key = "fooey";
            bool actual = target.ContainsValue(key);
            Assert.IsFalse(actual);
        }

        /// <summary>
        /// Negative: Null value
        /// </summary>
        [TestMethod]
        public void ContainsValueNegativeTest3()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            bool actual = target.ContainsValue(null);
            Assert.IsFalse(actual);
        }
        #endregion

        #region CopyTo
        /// <summary>
        /// Positive: Proper value
        /// </summary>
        [TestMethod]
        public void CopyToTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            int index = 0;
            Array array = Array.CreateInstance(typeof(KeyValuePair<string, object>), target.Count);
          
            target.CopyTo(array, index);
            Assert.AreEqual<int>(1, array.Length);

            KeyValuePair<string, object>[] actual = (KeyValuePair<string, object>[])array;
            Assert.AreEqual<string>(key, actual[0].Key);
            Assert.AreEqual<object>(value, actual[0].Value);
        }

        /// <summary>
        /// Fault: Destination array too small
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void CopyToFaultTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo1";
            int value = 1;
            target.Add(key, value);

            key = "foo2";
            target.Add(key, value);

            key = "foo3";
            target.Add(key, value);

            key = "foo4";
            target.Add(key, value);

            key = "foo5";
            target.Add(key, value);
            Assert.AreEqual<int>(5, target.Count);

            int index = 0;
            Array array = Array.CreateInstance(typeof(KeyValuePair<string, object>), target.Count - 2);

            target.CopyTo(array, index);
            Assert.Fail("Exception not thrown.");
        }

        /// <summary>
        /// Fault: Destination array is null
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentNullException))]
        public void CopyToFaultTest2()
        {
            Dictionary target = new Dictionary();

            int index = 0;
            KeyValuePair<string, object>[] array = null;

            target.CopyTo(array, index);
            Assert.Fail("Exception not thrown.");
        }

        /// <summary>
        /// Fault: Destination array is multi-dimensional
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void CopyToFaultTest3()
        {
            Dictionary target = new Dictionary();

            int index = 0;
            Array array = Array.CreateInstance(typeof(KeyValuePair<string, object>), 1, 1);

            target.CopyTo(array, index);
            Assert.Fail("Exception not thrown.");
        }

        /// <summary>
        /// Fault: Null parameters
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentNullException))]
        public void CopyToFaultTest4()
        {
            Dictionary target = new Dictionary();

            int index = 0;
            KeyValuePair<string, object>[] array = null;

            target.CopyTo(array, index);
            Assert.Fail("Exception not thrown.");
        }

        /// <summary>
        /// Fault: Out of range parameters
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void CopyToFaultTest5()
        {
            Dictionary target = new Dictionary();
            
            int index = -1;
            KeyValuePair<string, object>[] array = new KeyValuePair<string, object>[1];

            target.CopyTo(array, index);
            Assert.Fail("Exception not thrown.");
        }

        /// <summary>
        /// Fault: Out of range parameters
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void CopyToFaultTest6()
        {
            Dictionary target = new Dictionary();

            string key = "foo1";
            int value = 1;
            target.Add(key, value);

            int index = int.MaxValue;
            KeyValuePair<string, object>[] array = new KeyValuePair<string, object>[target.Count];

            target.CopyTo(array, index);
            Assert.Fail("Exception not thrown.");
        }

        /// <summary>
        /// Fault: Type mismatch parameters
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentTypeException))]
        public void CopyToFaultTest7()
        {
            Dictionary target = new Dictionary();

            string key = "foo1";
            int value = 1;
            target.Add(key, value);

            int index = 0;
            Array array = Array.CreateInstance(typeof(int), 1);            

            target.CopyTo(array, index);
            Assert.Fail("Exception not thrown.");
        }
        #endregion

        #region Equals
        /// <summary>
        /// Positive: Same reference
        /// </summary>
        [TestMethod]
        public void EqualsTest1()
        {
            Dictionary target = new Dictionary();
            Dictionary source = target;

            string key = "foo";
            string value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            bool actual = target.Equals(source);
            Assert.IsTrue(actual);
        }

        /// <summary>
        /// Negative: Different references
        /// </summary>
        [TestMethod]
        public void EqualsNegativeTest1()
        {
            Dictionary target = new Dictionary();
            Dictionary source = new Dictionary(); ;

            string key = "foo";
            string value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            source.Add(key, value);
            Assert.AreEqual<int>(1, source.Count);
            
            bool actual = target.Equals(source);
            Assert.IsFalse(actual);
        }
        #endregion

        #region GetGuidFromStringValue
        /// <summary>
        /// Positive: Proper value
        /// </summary>
        [TestMethod]
        public void GetGuidFromStringValueTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "94CAC1FC-61B2-4c69-9B76-BAC4C2528BEF";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            Guid? actual = target.GetGuidFromStringValue(key);
            Assert.IsNotNull(actual);
            Assert.AreEqual<string>(value.ToLower(), actual.ToString());
        }

        /// <summary>
        /// Positive: Proper value
        /// </summary>
        [TestMethod]
        public void GetGuidFromStringValueTest2()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "00000000-0000-0000-0000-000000000000";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            Guid? actual = target.GetGuidFromStringValue(key);
            Assert.IsNotNull(actual);
            Assert.AreEqual<string>(value.ToLower(), actual.ToString());
        }

        /// <summary>
        /// Negative: Empty string
        /// </summary>
        [TestMethod]
        public void GetGuidFromStringValueNegativeTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = string.Empty;
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            Guid? actual = target.GetGuidFromStringValue(key);
            Assert.IsNull(actual);
        }

        /// <summary>
        /// Negative: Incorrect type
        /// </summary>
        [TestMethod]
        public void GetGuidFromStringValueNegativeTest2()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            int value = 1;
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            Guid? actual = target.GetGuidFromStringValue(key);
            Assert.IsNull(actual);
        }

        /// <summary>
        /// Negative: Incorrect type
        /// </summary>
        [TestMethod]
        public void GetGuidFromStringValueNegativeTest3()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            Guid value = Guid.Empty;
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            Guid? actual = target.GetGuidFromStringValue(key);
            Assert.IsNull(actual);
        }
        #endregion

        #region GetValue
        /// <summary>
        /// Positive: Proper value
        /// </summary>
        [TestMethod]
        public void GetValueTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "bar";
            target.Add(key, value);

            string actual = target.GetValue<string>(key);
            Assert.AreEqual<object>(value, actual);
        }

        /// <summary>
        /// Positive: Proper value
        /// </summary>
        [TestMethod]
        public void GetValueTest2()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            object value = "bar";
            target.Add(key, value);

            string actual = target.GetValue<string>(key);
            Assert.AreEqual<object>(value, actual);
        }

        /// <summary>
        /// Negative: No match
        /// </summary>
        [TestMethod]
        public void GetValueNegativeTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";

            string actual = target.GetValue<string>(key);
            Assert.IsNull(actual);
        }

        /// <summary>
        /// Fault: Type mismatch
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentTypeException))]
        public void GetValueFaultTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            int value = 1;
            target.Add(key, value);

            string actual = target.GetValue<string>(key);
            Assert.Fail("Exception not thrown.");
        }
        #endregion

        #region Remove
        /// <summary>
        /// Positive: Proper value
        /// </summary>
        [TestMethod]
        public void RemoveTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            object value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            bool actual = target.Remove(key);
            Assert.AreEqual<int>(0, target.Count);
            Assert.IsTrue(actual);                        
        }

        /// <summary>
        /// Positive: Proper value multiple times
        /// </summary>
        [TestMethod]
        public void RemoveTest2()
        {
            Dictionary target = new Dictionary();

            string key1 = "foo";
            object value1 = "bar";
            target.Add(key1, value1);
            string key2 = "foo2";
            string value2 = "bar2";
            target.Add(key2, value2);
            Assert.AreEqual<int>(2, target.Count);

            target.Remove(key1);
            Assert.AreEqual<int>(1, target.Count);
            Assert.AreEqual<object>(value2, target[key2]);
        }

        /// <summary>
        /// Positive: Proper value as object
        /// </summary>
        [TestMethod]
        public void RemoveTest3()
        {
            Dictionary target = new Dictionary();

            object key = "foo";
            object value = "bar";
            target.Add(key, value);
            Assert.AreEqual<int>(1, target.Count);

            target.Remove(key);
            Assert.AreEqual<int>(0, target.Count);
        }

        /// <summary>
        /// Fault: Incorrect type
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentTypeException))]
        public void RemoveFaultTest1()
        {
            Dictionary target = new Dictionary();

            int key = int.MaxValue;

            target.Remove(key);
            Assert.Fail("Exception not thrown.");
        }

        /// <summary>
        /// Fault: Null value
        /// </summary>
        [TestMethod, ExpectedException(typeof(ArgumentNullException))]
        public void RemoveFaultTest2()
        {
            Dictionary target = new Dictionary();

            object item = null;

            target.Remove(item);
            Assert.Fail("Exception not thrown.");
        }
        #endregion

        #region TryGetValue
        /// <summary>
        /// Positive: Proper value
        /// </summary>
        [TestMethod]
        public void TryGetValueTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            string value = "bar";
            target.Add(key, value);

            string result;
            bool actual = target.TryGetValue<string>(key, out result);
            Assert.IsTrue(actual);
            Assert.AreEqual<object>(value, result);
        }

        /// <summary>
        /// Positive: Proper value
        /// </summary>
        [TestMethod]
        public void TryGetValueTest2()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            object value = "bar";
            target.Add(key, value);

            object result;
            bool actual = target.TryGetValue<object>(key, out result);
            Assert.IsTrue(actual);
            Assert.AreEqual<object>(value, result);
        }

        /// <summary>
        /// Negative: No match
        /// </summary>
        [TestMethod]
        public void TryGetValueNegativeTest1()
        {
            Dictionary target = new Dictionary();

            string key = "foo";

            object result;
            bool actual = target.TryGetValue<object>(key, out result);
            Assert.IsFalse(actual);
            Assert.IsNull(result);
        }

        /// <summary>
        /// Negative: Type mismatch
        /// </summary>
        [TestMethod]
        public void TryGetValueNegativeTest2()
        {
            Dictionary target = new Dictionary();

            string key = "foo";
            int value = 1;
            target.Add(key, value);

            string result;
            bool actual = target.TryGetValue<string>(key, out result);
            Assert.IsFalse(actual);
            Assert.IsNull(result);
        }
        #endregion
    }
}
